Implementing Loops and Iteration Techniques in Kotlin
Course: Android App Development
Topic: Implementing Loops and Iteration Techniques
Course Link: Android App Development Course
Demo Link: Register for Course Demo
Website: JustAcademy
1. Introduction to Loops in Kotlin
Loops are fundamental programming structures that allow developers to execute a block of code repeatedly. Instead of writing the same statements multiple times, a loop performs repetitive tasks based on a condition or a collection of elements.
In Android app development, loops are useful for displaying lists of products, processing user records, calculating totals, validating collections of data, generating reports, and performing repetitive operations.
Kotlin provides several looping techniques, including for, while, and do-while loops. It also supports loop-control statements such as break and continue, along with higher-order collection functions such as forEach, map, and filter.
Example
fun main() {
for (number in 1..5) {
println("Number: $number")
}
}
Output:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
The loop executes five times and prints each number from 1 to 5.
2. Learning Objectives
After completing this topic, learners should be able to:
- Understand the purpose and importance of loops in Kotlin.
- Implement
for, while, and do-while loops.
- Use ranges and progression operators for iteration.
- Iterate through arrays, lists, sets, and maps.
- Use
break and continue to control loop execution.
- Understand nested loops and their applications.
- Apply collection functions for processing data.
- Avoid infinite loops and common iteration errors.
- Implement loops in practical Android development scenarios.
3. Understanding the for Loop
The for loop is used to iterate through a range, array, collection, or another supported sequence of values. Kotlin's for loop is particularly useful when the elements to process are already available.
3.1 Basic for Loop
fun main() {
for (i in 1..5) {
println(i)
}
}
The expression 1..5 creates a range that includes both 1 and 5. The loop processes every value in that range.
3.2 Iterating Through a List
fun main() {
val fruits = listOf("Apple", "Banana", "Mango")
for (fruit in fruits) {
println(fruit)
}
}
The loop retrieves each fruit from the list and prints it. This technique is useful when processing lists of names, products, categories, or messages in an Android application.
3.3 Iterating Through an Array
fun main() {
val marks = arrayOf(85, 90, 78, 92)
for (mark in marks) {
println("Mark: $mark")
}
}
Each element is assigned to the loop variable mark during an iteration.
3.4 Iterating with Index Values
Sometimes, a program needs both the position and the value of an element. Kotlin provides withIndex() for this purpose.
fun main() {
val students = listOf("Aarav", "Priya", "Rohan")
for ((index, student) in students.withIndex()) {
println("${index + 1}. $student")
}
}
Output:
1. Aarav
2. Priya
3. Rohan
This technique is useful for numbered lists, menus, rankings, and displaying items with their positions.
4. Working with Ranges and Progressions
Kotlin provides range and progression operators that control which values a loop processes.
4.1 The Range Operator (..)
The .. operator creates an inclusive range, meaning that both the starting and ending values are included.
for (number in 1..5) {
println(number)
}
This loop prints numbers from 1 through 5.
4.2 The until Operator
The until operator creates a range that excludes the upper limit.
for (number in 1 until 5) {
println(number)
}
The output contains 1, 2, 3, and 4. The value 5 is excluded.
4.3 The downTo Operator
The downTo operator iterates in descending order.
for (number in 5 downTo 1) {
println(number)
}
This is useful for countdowns, reverse sequences, and descending numerical calculations.
4.4 The step Operator
The step operator specifies the interval between successive values in a progression.
for (number in 0..10 step 2) {
println(number)
}
Output: 0, 2, 4, 6, 8, 10.
4.5 Combining Range Operators
fun main() {
println("Ascending:")
for (i in 1..5 step 2) {
println(i)
}
println("Descending:")
for (i in 10 downTo 2 step 2) {
println(i)
}
}
Combining these operators provides control over the starting point, ending point, direction, and interval of iteration.
5. Understanding the while Loop
A while loop repeatedly executes a block of code as long as its condition remains true. The condition is evaluated before the loop body executes.
5.1 Basic while Loop
fun main() {
var count = 1
while (count <= 5) {
println(count)
count++
}
}
The loop starts with count = 1. After every iteration, the value increases by one. When the value becomes 6, the condition is false and the loop stops.
5.2 Using while for User Input Processing
A while loop can process values while a particular condition is satisfied. The following example simulates processing a limited number of pending tasks.
fun main() {
var pendingTasks = 3
while (pendingTasks > 0) {
println("Processing task $pendingTasks")
pendingTasks--
}
println("All tasks processed")
}
This example demonstrates how a changing condition controls the number of iterations.
5.3 When to Use while
- When the number of iterations is not known in advance.
- When repetition depends on a changing condition.
- When waiting for a program state to change within a controlled algorithm.
- When processing data until a termination condition is reached.
In Android applications, avoid using blocking loops on the main UI thread to wait for network responses or user actions. Use coroutines, callbacks, or other asynchronous techniques instead.
6. Understanding the do-while Loop
A do-while loop executes the loop body first and checks the condition afterward. Consequently, its body always runs at least once.
6.1 Basic Example
fun main() {
var number = 1
do {
println(number)
number++
} while (number <= 5)
}
The loop prints numbers from 1 to 5. The condition is evaluated after each execution of the body.
6.2 Difference Between while and do-while
| Feature |
while |
do-while |
| Condition check |
Before the body |
After the body |
| Minimum executions |
Zero |
One |
| Best suited for |
Repetition only while a condition is true |
Operations that must run at least once |
| Syntax |
while (condition) { ... } |
do { ... } while (condition) |
6.3 Example with a False Initial Condition
fun main() {
var number = 10
while (number < 5) {
println("while executed")
}
do {
println("do-while executed")
} while (number < 5)
}
The while body does not execute because its initial condition is false. The do-while body executes once before its condition is checked.
7. Loop Control Statements
Loop-control statements change the normal flow of iteration. Kotlin supports break to terminate a loop and continue to skip the remaining statements in the current iteration.
7.1 The break Statement
The break statement immediately terminates the nearest enclosing loop.
fun main() {
for (number in 1..10) {
if (number == 6) {
break
}
println(number)
}
}
Output: 1, 2, 3, 4, 5.
When the loop reaches 6, it stops without printing that value.
7.2 The continue Statement
The continue statement skips the remaining statements in the current iteration and proceeds to the next iteration.
fun main() {
for (number in 1..5) {
if (number == 3) {
continue
}
println(number)
}
}
Output: 1, 2, 4, 5.
The value 3 is skipped, but the loop continues processing the remaining numbers.
7.3 Using break in a Search Operation
fun main() {
val numbers = listOf(10, 20, 30, 40, 50)
for (number in numbers) {
if (number == 30) {
println("Value found")
break
}
}
}
Once the target value is found, the loop stops searching. This can avoid unnecessary work in simple sequential searches.
7.4 Labeled break and continue
Kotlin supports labels for controlling nested loops. A labeled break exits the specified enclosing loop, while a labeled continue proceeds to the next iteration of the specified loop.
fun main() {
outer@ for (i in 1..3) {
for (j in 1..3) {
if (i == 2 && j == 2) {
break@outer
}
println("i=$i, j=$j")
}
}
}
The labeled break exits the outer loop when both conditions are met. Use labels sparingly because deeply nested control flow can make code harder to understand.
8. Nested Loops
A nested loop is a loop placed inside another loop. For every iteration of the outer loop, the inner loop can execute its own sequence of iterations.
8.1 Basic Nested Loop
fun main() {
for (i in 1..3) {
for (j in 1..2) {
println("Outer: $i, Inner: $j")
}
}
}
The outer loop runs three times. The inner loop runs twice for each outer iteration, producing six combinations.
8.2 Printing a Pattern
fun main() {
for (row in 1..5) {
for (column in 1..row) {
print("* ")
}
println()
}
}
Output:
*
* *
* * *
* * * *
* * * * *
This example demonstrates nested iteration and can be used to practice loops, patterns, and output formatting.
8.3 Multiplication Table
fun main() {
for (number in 1..5) {
for (multiplier in 1..10) {
println("$number x $multiplier = ${number * multiplier}")
}
}
}
Nested loops are useful for tabular calculations, matrix processing, grid-based algorithms, and generating combinations. However, their execution time can increase rapidly when both loops process large datasets.
9. Iterating Through Collections
Kotlin collections provide convenient ways to store and process groups of values. Iteration techniques can be applied to lists, sets, maps, and arrays.
9.1 Iterating Through a List
fun main() {
val products = listOf("Laptop", "Phone", "Tablet")
for (product in products) {
println(product)
}
}
9.2 Iterating Through a Set
fun main() {
val categories = setOf("Electronics", "Books", "Clothing")
for (category in categories) {
println(category)
}
}
A set stores unique values. Do not rely on a particular iteration order unless the selected collection type explicitly guarantees it.
9.3 Iterating Through a Map
fun main() {
val user = mapOf(
"name" to "Riya",
"city" to "Mumbai",
"role" to "Developer"
)
for ((key, value) in user) {
println("$key: $value")
}
}
Map destructuring allows the loop to access both the key and the value of each entry.
9.4 Iterating Through an Array with Indices
fun main() {
val scores = arrayOf(80, 90, 75, 95)
for (index in scores.indices) {
println("Index $index: ${scores[index]}")
}
}
The indices property provides the valid index range of the array. This helps avoid manually calculating the final index.
10. Collection Iteration Functions
In addition to traditional loops, Kotlin offers collection functions that make many data-processing operations concise and expressive.
10.1 The forEach Function
The forEach function executes an action for every element in a collection.
fun main() {
val names = listOf("Amit", "Neha", "Karan")
names.forEach { name ->
println(name)
}
}
This is useful when the same action must be applied to every element. For complex control flow, a traditional loop may be easier to read.
10.2 The map Function
The map function transforms each element into a new value and returns a list of the transformed results.
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
val squares = numbers.map { number ->
number * number
}
println(squares)
}
Output: [1, 4, 9, 16, 25].
10.3 The filter Function
The filter function creates a collection containing only the elements that satisfy a condition.
fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenNumbers = numbers.filter { number ->
number % 2 == 0
}
println(evenNumbers)
}
Output: [2, 4, 6].
10.4 The reduce Function
The reduce function combines collection elements into a single result. It requires a non-empty collection because the first element becomes the initial accumulator.
fun main() {
val numbers = listOf(10, 20, 30, 40)
val total = numbers.reduce { sum, number ->
sum + number
}
println(total)
}
Output: 100. When a collection might be empty, consider fold() with an initial value or another suitable approach.
10.5 Choosing Between Loops and Collection Functions
| Technique |
Purpose |
Example |
for |
General iteration with clear control flow |
Processing every product |
forEach |
Applying an action to each element |
Printing each name |
map |
Transforming every element |
Converting prices to formatted values |
filter |
Selecting matching elements |
Finding products in stock |
reduce |
Combining elements into one result |
Calculating a total |
11. Implementing Loops in Android Applications
Loops are commonly used in Android applications to prepare data, calculate values, and process collections before displaying results in the user interface.
11.1 Displaying a List of Products
fun main() {
val products = listOf(
"Laptop",
"Smartphone",
"Headphones",
"Smartwatch"
)
for (product in products) {
println("Product: $product")
}
}
This demonstrates processing a product collection. In a real Android application, a RecyclerView or Jetpack Compose's LazyColumn is generally more suitable for displaying long or scrollable lists than manually creating every view in a loop.
11.2 Calculating a Shopping Cart Total
fun main() {
val prices = listOf(500.0, 1200.0, 750.0)
var total = 0.0
for (price in prices) {
total += price
}
println("Total: $total")
}
The loop adds each price to the running total. For real financial applications, consider using integer minor units or BigDecimal to avoid floating-point precision issues.
11.3 Filtering Active Users
data class User(
val name: String,
val isActive: Boolean
)
fun main() {
val users = listOf(
User("Aarav", true),
User("Priya", false),
User("Rohan", true)
)
for (user in users) {
if (user.isActive) {
println(user.name)
}
}
}
This example checks each user and prints the names of active users. The same selection can be expressed with users.filter { it.isActive } when a filtered collection is needed.
11.4 Processing Data in Jetpack Compose
Jetpack Compose provides collection-aware UI components. A LazyColumn is useful for displaying a scrollable list of items without creating every item at once.
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun ProductList() {
val products = listOf(
"Laptop",
"Smartphone",
"Headphones"
)
LazyColumn {
items(products) { product ->
Text(text = product)
}
}
}
This example assumes that the project has Jetpack Compose and the required dependencies configured. The items() function manages list-item composition, making it preferable to manually creating a large number of UI elements in a regular loop.
11.5 Avoiding Blocking Loops on the Main Thread
Android's main thread handles user interaction and UI updates. A long-running or infinite loop on this thread can make an application unresponsive.
For tasks involving network requests, delays, or background calculations, use appropriate asynchronous techniques such as Kotlin coroutines, dispatchers, and lifecycle-aware scopes. A loop itself does not make an operation asynchronous.
12. Infinite Loops and Common Errors
An infinite loop occurs when its termination condition never becomes false or when the loop has no reachable exit. Such loops can consume CPU resources and, in Android applications, may cause the interface to freeze.
12.1 Missing Counter Update
Incorrect example:
var count = 1
// Incorrect: count never changes.
// while (count <= 5) {
// println(count)
// }
The condition remains true because count is never updated.
Correct example:
var count = 1
while (count <= 5) {
println(count)
count++
}
12.2 Incorrect Boundary Conditions
for (number in 1 until 5) {
println(number)
}
This loop intentionally excludes 5. If the requirement is to include 5, use 1..5.
12.3 Modifying a Collection During Iteration
Changing a mutable collection while iterating over it with an iterator or a collection loop can lead to unexpected behavior or a ConcurrentModificationException, depending on the collection and operation.
Safer approach when removing matching values:
fun main() {
val numbers = mutableListOf(1, 2, 3, 4, 5)
numbers.removeAll { number ->
number % 2 == 0
}
println(numbers)
}
The output is [1, 3, 5]. The collection function expresses the removal condition without manually removing elements from inside a standard iteration loop.
12.4 Common Loop Problems
| Problem |
Cause |
Solution |
| Infinite loop |
Termination condition never becomes false |
Check variable updates and exit conditions |
| Missing final value |
Using an exclusive range |
Use the correct range operator |
| Incorrect index |
Using an invalid array or list index |
Use indices or safe indexing |
| Slow execution |
Unnecessary nested iterations |
Optimize the algorithm and avoid repeated work |
| UI freezing |
Long-running loop on the main thread |
Use asynchronous background processing where appropriate |
| Unexpected collection errors |
Unsafe modification during iteration |
Use safe removal functions or a suitable iterator |
| Skipped processing |
Using continue or break incorrectly |
Review loop-control conditions |
13. Best Practices for Implementing Loops
- Choose the loop type that matches the problem.
- Use a
for loop when iterating through a known range or collection.
- Use
while when repetition depends on a condition checked before execution.
- Use
do-while when the body must execute at least once.
- Make sure loop termination conditions can eventually become false.
- Use meaningful variable names such as
index, product, or student.
- Prefer collection functions such as
filter and map when they make the intended operation clearer.
- Avoid deeply nested loops when a simpler algorithm is available.
- Use
indices or withIndex() when working with collection positions.
- Avoid modifying collections unsafely during iteration.
- Do not block Android's main thread with expensive or indefinite loops.
- Test empty collections, single-element collections, and boundary values.
- Measure performance before optimizing code unnecessarily.
14. Practical Exercises
Exercise 1: Print Numbers
Write a Kotlin program that prints numbers from 1 to 20 using a for loop.
Exercise 2: Even Numbers
Print all even numbers between 1 and 50 using a range and the step operator.
Exercise 3: Countdown Timer Logic
Use a while loop to print numbers from 10 down to 1, followed by a completion message. This exercise models countdown logic only; it does not implement a real-time Android timer.
Exercise 4: Sum of Elements
Create a list of integers and calculate the sum of its values using a for loop.
Exercise 5: Search for a Product
Create a list of product names. Search for a particular product and stop the loop when it is found using break.
Exercise 6: Skip Invalid Values
Iterate through a list of numbers and use continue to skip negative values.
Exercise 7: Multiplication Tables
Use nested loops to print multiplication tables from 1 to 10.
Exercise 8: Filter Active Users
Create a list of user records and display only the users whose active status is true.
15. Mini Project: Shopping Cart Summary
Project Objective: Develop a Kotlin program that processes shopping cart items using loops, conditions, and collection operations.
Project Requirements
- Create a list of product names.
- Create a corresponding list of product prices.
- Iterate through the products and display their names and prices.
- Calculate the total cost of all items.
- Identify products priced above a specified threshold.
- Display a message when the cart is empty.
- Use clear variable names and appropriate data types.
Sample Implementation
data class Product(
val name: String,
val price: Double
)
fun main() {
val cart = listOf(
Product("Keyboard", 1200.0),
Product("Mouse", 650.0),
Product("Monitor", 8500.0)
)
if (cart.isEmpty()) {
println("Your cart is empty")
} else {
var total = 0.0
for ((index, product) in cart.withIndex()) {
println(
"${index + 1}. ${product.name}: ${product.price}"
)
total += product.price
}
println("Cart total: $total")
println("Products above 1000:")
for (product in cart) {
if (product.price > 1000.0) {
println(product.name)
}
}
}
}
Expected Learning Outcomes
- Apply loops to process structured data.
- Use conditions inside loops.
- Calculate aggregate values using iteration.
- Access list elements and their indices.
- Combine data classes and collections in Kotlin.
16. Interview Questions and Answers
Q1. What is a loop in Kotlin?
A loop is a control structure that repeatedly executes a block of code based on a range, collection, or condition.
Q2. What types of loops does Kotlin support?
Kotlin supports for, while, and do-while loops.
Q3. What is the difference between for and while?
A for loop commonly iterates through a range or collection, while a while loop repeats as long as its condition is true.
Q4. Why does a do-while loop execute at least once?
Because its condition is checked after the loop body executes for the first time.
Q5. What is the difference between break and continue?
break terminates the nearest enclosing loop. continue skips the remaining statements in the current iteration and moves to the next iteration.
Q6. What is a nested loop?
A nested loop is a loop inside another loop. It is commonly used for patterns, matrices, and combinations of values.
Q7. What is the difference between 1..5 and 1 until 5?
1..5 includes both endpoints, while 1 until 5 excludes the upper endpoint.
Q8. What does the step operator do?
The step operator controls the interval between successive values in a numeric progression.
Q9. How can you iterate through a list in Kotlin?
You can use a for loop, forEach, or other collection functions depending on the operation required.
Q10. What is an infinite loop?
An infinite loop is a loop that does not reach a terminating condition or exit, causing it to continue indefinitely.
Q11. How can you access both an element and its index?
Use withIndex() or iterate through the collection's indices when appropriate.
Q12. What is the purpose of the map function?
The map function transforms each element of a collection and returns a list of the transformed results.
Q13. What is the purpose of filter?
The filter function returns a collection containing elements that satisfy a specified condition.
Q14. Why should long-running loops be avoided on Android's main thread?
Long-running work on the main thread can block UI rendering and input processing, making the application unresponsive. Expensive work should be handled using appropriate asynchronous techniques.
Q15. How can you avoid errors when removing items during iteration?
Use suitable collection operations, such as removeAll with a predicate, or use a supported iterator-removal approach instead of modifying the collection unsafely during traversal.
17. Quick Revision Checklist
- Understand the purpose of loops and iteration.
- Practice
for, while, and do-while.
- Know the difference between inclusive and exclusive ranges.
- Use
step and downTo correctly.
- Understand
break, continue, and loop labels.
- Practice nested loops and pattern generation.
- Iterate through arrays, lists, sets, and maps.
- Understand
forEach, map, filter, and reduce.
- Prevent infinite loops and invalid index access.
- Use safe collection-modification techniques.
- Keep long-running operations off Android's main thread.
- Practice loop-based calculations and small Kotlin projects.
18. Conclusion
Loops and iteration techniques are essential for processing data efficiently in Kotlin. The for loop is useful for ranges and collections, while while and do-while provide condition-based repetition. Statements such as break and continue allow developers to control how loops execute.
Kotlin collection functions provide expressive alternatives for transforming, filtering, and combining data. By understanding these techniques, developers can write clearer code for Android application logic, product processing, data calculations, and list-based user interfaces.
Learn Android App Development with JustAcademy
Strengthen your Kotlin programming skills and explore practical Android application development through the JustAcademy course.
Course Details: View Android App Development Course
Register for a Demo: Register for Course Demo
JustAcademy Website: Visit JustAcademy